package xpn.platform.modules.sys.org;

import com.google.common.base.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import xpn.platform.modules.sys.user.SysUser;
import xpn.platform.modules.sys.user.SysUserService;
import org.springframework.context.annotation.Lazy;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;


/**
 * 组织机构服务实现
 *
 * @author bobatkm Oct 18, 2017
 */
@Service
public class SysOrgServiceImpl implements SysOrgService {

    @Autowired
    SysOrgDAO orgDao;

    @Autowired
    @Lazy
    SysUserService userService;

    @Override
    public List<SysOrg> findSendeeSelectOrgs(String roleCondition, Integer ouLevel, Integer ouType,
                                             String starterId, String mySenderId, String specifiedUsersHref,
                                             String xpnTokenName, String token) {
        // 情形1 ：角色条件和用户条件都未指定
        if (Strings.isNullOrEmpty(roleCondition) && (ouLevel < 0 || ouType < 0)) {
            // 返回所有的O
            return orgDao.findByParentOrgIsNull();
        }

        // 获取当前用户curUser
        SysUser curUser = userService.getSessionUser();

        // 情形2 ： 未指定角色：返回指定机构和其所有祖先机构
        if (Strings.isNullOrEmpty(roleCondition)) {
            return findOrgByOuCondition(curUser, ouLevel, ouType);
        }

        // 情形3： 指定了角色条件
        List<SysOrg> orgList = new ArrayList<>();

        // 1 获取当前用户的所属的指定ouLevel的机构名称userOU，如果没有返回空列表
        String userOUName = userService.getOUName(curUser, ouLevel);
        if ("".equals(userOUName) && ouLevel > -1) {
            return orgList;
        }

        // 2 根据角色条件查找所有符合条件的用户列表roleUserList，如果为空，则返回空列表
        List<SysUser> roleUserList = userService.findByRoleCondition(roleCondition, starterId, mySenderId, specifiedUsersHref, xpnTokenName, token);
        if (roleUserList.size() == 0) {
            return orgList;
        }

        // 3 遍历用户列表roleUserList，获取符合ouLevel和ouType的用户列表userList
        List<SysUser> userList = userService.filterUsers(roleUserList, userOUName, ouLevel, ouType);
        if (userList.size() == 0) {
            return orgList;
        }

        // 4 遍历用户列表userList，返回每个用户的所属机构极其所有祖先列表
        for (SysUser user : userList) {
            SysOrg userOrg = user.getOrg();
            if (orgList.contains(userOrg)) {
                continue;
            }
            addOrgAndAncestorsOfOrg(userOrg, orgList);
        }

        return new ArrayList<>(new HashSet<>(orgList));
    }

    // 获取对于Rest转换安全的机构列表
    @Override
    public List<SysOrg> getSafeOrgListForRestConvert(List<SysOrg> orgList) {
        if (orgList == null) {
            return orgList;
        }
        if (orgList.isEmpty()) {
            return orgList;
        }

        return orgList;
    }

    /**
     * 查找符合指定ou条件的机构列表
     * @param curUser
     * @param ouLevel
     * @param ouType
     * @return
     */
    private List<SysOrg> findOrgByOuCondition(SysUser curUser, int ouLevel, int ouType) {
        List<SysOrg> orgList = new ArrayList<>();

        // 获取当前用户的机构
        SysOrg curUserOrg = curUser.getOrg();
        // 当前用户无机构
        if (curUserOrg == null) {
            return orgDao.findByParentOrgIsNull();
        }

        // 获取当前用户指定层次的机构
        SysOrg ouOrg = this.getOUOrg(curUserOrg, ouLevel);
        // 当前用户无指定层次的机构
        if (ouOrg == null) {
            return orgList;
        }
        // 本ou
        if (ouType == 0) {
//            addOrgAndAncestorsOfOrg(ouOrg, orgList);
            orgList.add(ouOrg);
            return orgList;
        } else { // 外ou
            // 获得父机构
            SysOrg parentOrg = ouOrg.getParentOrg();
            // 无父机构：返回顶层的所有机构（排除当前机构）
            if (parentOrg == null) {
                return orgDao.findByParentOrgIsNullAndIdNot(ouOrg.getId());
            }

            // 返回父机构的所有儿子机构
            List<SysOrg> children = orgDao.findByParentOrg(parentOrg);
            // 排除当前机构
            children.remove(ouOrg);

            if (children.size() > 0) {
                addOrgAndAncestorsOfOrg(parentOrg, orgList);
                orgList.addAll(children);
            }

            return orgList;
        }
    }

    /**
     * 把指定机构及其所有祖先机构加入指定列表
     */
    private List<SysOrg> addOrgAndAncestorsOfOrg(SysOrg org, List<SysOrg> orgList) {
        for (; org != null; org = org.getParentOrg()) {
            if (!orgList.contains(org)) {
                orgList.add(org);
            }
        }
        return orgList;
    }

    @Override
    public SysOrg getOUOrg(SysOrg paramOrg, int level) {
        List<SysOrg> orgList = new ArrayList<>();
        for (SysOrg org = paramOrg; org != null; org = org.getParentOrg()) {
            orgList.add(org);
        }
        if (orgList.size() < level + 1) {
            return null;
        } else {
            return (orgList.get(orgList.size() - level - 1));
        }
    }

    @Override
    public ArrayList<Long> getSelfAndChildIds(Long id,ArrayList<Long> ret)
    {
        ret.add(id);
        SysOrg org=orgDao.getOne(id);
        Set<SysOrg> child = org.getChildren();
        if(child.size()>0){
            for(SysOrg c:child){
                getSelfAndChildIds(c.getId(),ret);
            }
        }
        return ret;

    }

    @Override
    public SysOrg getRelateOrgByType(Long id,int type)
    {
        SysOrg ret=null;
        SysOrg org=orgDao.getById(id);
        if(org.getType()!=null){
            if(org.getType().equals(type)){
                return org;
            }else{
                if(org.getParentOrg()!=null){
                    return getRelateOrgByType(org.getParentOrg().getId(),type);
                }
            }
        }
        return ret;
    }

}
